package com.qianyitian.hope2.analyzer.service;

import com.alibaba.fastjson.JSON;
import com.qianyitian.hope2.analyzer.analyzer.*;
import com.qianyitian.hope2.analyzer.model.*;
import com.qianyitian.hope2.analyzer.util.Utils;
import com.qianyitian.hope2.sdk.Securities;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class DemarkService4Demo {
    private Logger logger = LoggerFactory.getLogger(getClass());
    @Autowired
    private StockService favoriteStockService;

    public String demarkBacktrackForTest(String code, Integer tNumber, String t) {
        String seriesData = null;
        final int days2NowNumber = tNumber;
        try {
            return stockReportForTest(code, tNumber, t);
        } catch (Exception e) {
            seriesData = e.toString();
            logger.error("demark error " + code, e);
        }
        return seriesData;
    }


    //生成单个证券的报告
    protected String stockReportForTest(String code, int tNumber, String t) {
        Securities securities = getStockFromSpider(code, t);
        if (securities == null) {
            return "stock not exists " + code;
        }
        Map<String, Object> map = new HashMap<>();
        map.put("code", securities.getCode());
        map.put("name", securities.getName());

        List<Number[]> bars = convert2ChartFormat(securities);
        logger.error(t + "   bar number is " + bars.size());
        map.put("bars", bars);

        ResultInfo resultInfo = null;
        //buy flags
        {
            DemarkAnalyzer4Demo stockAnalyzer = new DemarkAnalyzer4Demo();
            stockAnalyzer.setDaysToNow(tNumber);
            resultInfo = analyze(stockAnalyzer, securities);
            if (resultInfo != null) {
                map.put("flag", resultInfo.getData().get("flag"));
            }
        }
        //sell flags
        {
            UnDemarkAnalyzer4Demo unStockAnalyzer = new UnDemarkAnalyzer4Demo();
            unStockAnalyzer.setDaysToNow(tNumber);
            ResultInfo unResultInfo = analyze(unStockAnalyzer, securities);
            if (unResultInfo != null) {
                map.put("flagSell", unResultInfo.getData().get("flag"));
            }
        }

        //计算收益
        {
            if (resultInfo != null) {
                FixInvestmentAccount sameCostAccountDay = new FixInvestmentAccount(tNumber);
                sameCostAccountDay.run(bars, FixInvestmentAccount.SAME_COST_EVERY_DAY);
                Profit sameCostProfitDay = sameCostAccountDay.getProfit();


                FixInvestmentAccount sameAmountAccountWeek = new FixInvestmentAccount(tNumber);
                sameAmountAccountWeek.run(bars, FixInvestmentAccount.SAME_COST_EVERY_WEEK);
                Profit sameAmountProfitWeek = sameAmountAccountWeek.getProfit();

                FixInvestmentAccount sameAmountAccountMonth = new FixInvestmentAccount(tNumber);
                sameAmountAccountMonth.run(bars, FixInvestmentAccount.SAME_COST_EVERY_MONTH);
                Profit sameAmountProfitMonth = sameAmountAccountMonth.getProfit();


                List<DemarkFlag> flagList = (List<DemarkFlag>) resultInfo.getData().get("flag");
                List<Long> bsBuyPointDateList = flagList.stream().map(DemarkFlag::getSetup).collect(Collectors.toList());
                List<Long> bcBuyPointDateList = flagList.stream().map(DemarkFlag::getCountdown).collect(Collectors.toList());

                FixInvestmentAccount demarkAccount = new FixInvestmentAccount(tNumber);
                List<Long> all = new ArrayList<>();
                all.addAll(bsBuyPointDateList);
                all.addAll(bcBuyPointDateList);
                demarkAccount.run(bars, all);
                Profit demarkProfit = demarkAccount.getProfit();

                FixInvestmentAccount demarkAccountWithoutBC = new FixInvestmentAccount(tNumber);
                demarkAccountWithoutBC.run(bars, bsBuyPointDateList);
                Profit demarkProfitWithoutBC = demarkAccountWithoutBC.getProfit();


//                map.put("profit1", demarkProfit);
//                map.put("profit2", sameCostProfitDay);
//                map.put("profit3", sameAmountProfitWeek);
//                map.put("profit4", sameAmountProfitMonth);
//                map.put("profit5", demarkProfitWithoutBC);
            }
        }

        String content = JSON.toJSONString(map);
        return content;
    }

    private Securities getStockFromSpider(String code, String t) {
        return favoriteStockService.getStockInMinutes(code, t);
    }

    protected List<Number[]> convert2ChartFormat(Securities stock) {
        ZoneOffset offset = ZoneOffset.UTC;
        List<Number[]> collect = stock.getBarSeries().getBars().stream().map(bar -> {
            long dateMilliSeconds = 1000 * bar.getTime().toEpochSecond(offset);
            Number[] row = new Number[]{dateMilliSeconds, bar.getOpen(), bar.getHigh(), bar.getLow(), bar.getClose(), bar.getTurnoverRate()};
            return row;
        }).collect(Collectors.toList());
        return collect;
    }

    public ResultInfo analyze(Demark4DemoAnalyzer analyzer, Securities stock) {
        ResultInfo resultInfo = new ResultInfo();
        resultInfo.setCode(stock.getCode());
        resultInfo.setName(stock.getName());

        try {
            if (!analyzer.analyze(resultInfo, stock)) {
                return null;
            }
        } catch (Exception e) {
            logger.error("analyzer " + analyzer.getClass().getName() + " stock " + stock.getCode(), e);
        }

        //get stock url
        //http://quotes.money.163.com/0601899.htmls
        resultInfo.setUrl(Utils.convert163StockURL(stock.getCode()));
        return resultInfo;
    }
}




